package com.example.emos.wx.config.xss;

import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HtmlUtil;
import cn.hutool.json.JSONUtil;
import io.netty.util.internal.StringUtil;
import org.springframework.util.StringUtils;
import org.springframework.web.util.HtmlUtils;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 设计抵御即跨站脚本攻击
 * @author liujingmao
 * @version 1.0
 * @date 2021/1/31 15:18
 */
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
    public XssHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
    }

    @Override
    public String getHeader(String name) {
        return super.getHeader(name);
    }

    @Override
    public String getParameter(String name) {

        String value = super.getParameter(name);
        if(!StrUtil.hasEmpty(value)){
            value = HtmlUtil.filter(value);
        }
        return value;
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        InputStream inputStream = super.getInputStream();
        InputStreamReader reader = new InputStreamReader(inputStream);
        BufferedReader bufferedReader = new BufferedReader(reader);
        StringBuffer body = new StringBuffer();
        String line = bufferedReader.readLine();
        while (line!=null){
            body.append(line);
            line=bufferedReader.readLine();
        }
        bufferedReader.close();
        reader.close();
        inputStream.close();

        Map<String,Object> map = JSONUtil.parseObj(body.toString());
        Map<String,Object> resultMap = new HashMap<>(map.size());

        for(String key: map.keySet()){
            Object val = map.get(key);
            if(map.get(key) instanceof String){
                resultMap.put(key,HtmlUtil.filter(val.toString()));
            } else {
                resultMap.put(key,HtmlUtil.filter(val.toString()));
            }
        }

        String str = JSONUtil.toJsonStr(resultMap);
        final ByteArrayInputStream bain = new ByteArrayInputStream(str.getBytes());
        return  new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener listener) {

            }

            @Override
            public int read() throws IOException {
                return bain.read();
            }
        };

    }

    @Override
    public Map<String, String[]> getParameterMap() {

        Map<String,String[]> parameters = super.getParameterMap();
        Map<String,String[]> map = new LinkedHashMap<>();

        if(parameters!=null){
            for(String key:parameters.keySet()){
                String[] values = parameters.get(key);
                for(int i = 0;i<values.length;i++){
                    String value = values[i];
                    if(!StrUtil.hasEmpty(value)){
                        value=HtmlUtil.filter(value);
                    }
                    values[i] = value;
                }
                map.put(key,values);
            }
        }
        return map;
    }

    @Override
    public String[] getParameterValues(String name) {
        String []values = super.getParameterValues(name);
        if(values!=null){
            for(int i=0;i<values.length;i++){
                String value = values[i];
                if(!StrUtil.hasEmpty(values [i])){
                    value=HtmlUtil.filter(values[i]);
                }
                values[i] = value;
            }
        }
        return values;
    }
}
